<?php
class UsersController extends AppController {

	var $name = 'Users';
	var $uses = array('Group', 'User', 'Application', 'Score', 'Studyinterest', 'Courselist', 'School');

///////////////////////////////////////////////////////////////////////////////	

function beforeFilter() {
	parent::beforeFilter();
	$this->Auth->allow('login', 'logout');
	if (isset($this->passedArgs[0]) && $this->Auth->user('group_id') != 1) {
  	$aco = $this->Acl->Aco->findByModelAndForeignKey('User', $this->passedArgs[0]);
    $aro = $this->Acl->Aro->findByModelAndForeignKey('User', $this->Auth->user('id'));
    if (!$this->Acl->check($aro['Aro'], $aco['Aco'])) {
                $this->Session->setFlash($this->Auth->authError);
                $this->redirect($this->referer());
    }
	}
}

function login() {

	//If we successfully logged in then lets redirect
	// based on roles. 
	$user = $this->Auth->user();
	//If an element requested this information return it.
	if (isset($this->params['requested'])) {
		$this->Session->delete('Message.auth');
		return $user;
	}
	
	//Otherwise if we have a user, do some redirecting to the appropriate homes.
	if ($user) {
		
		switch($user['User']['group_id']) {
			case 1: //Administrators
				$this->redirect(array('controller' => 'Applications',
															'action' => 'index'));
				break;
			case 2: //Applicants
				//Applicants must have a valid Application to login.
				$app = $this->Application->findByUserId($user['User']['id'], array('fields' => 'id'));
				$this->Session->write('Auth.User.app_id', $app['Application']['id']);
				$this->redirect(array('controller' => 'Applications',
															'action' => 'view', $app['Application']['id']));
				break;
			case 3: //Faculty
			case 5: //Students
				$this->redirect(array('controller' => 'Applications',
															'action' => 'search'));
				break;
			case 4: //Staff
				$this->redirect(array('controller' => 'Pages',
															'action' => 'home'));
				break;
			default: // an unrecognized role. 
				//notify the user and logout.
				$this->Session->setFlash(__('Unrecognized role', true), 'flash_failure', 'auth');
				$this->redirect(array('controller' => 'Users',
															'action' => 'logout'));
		}
		
	}
	
	//Simplified layout for login.
	$this->layout = 'login';
	//Set the window title.
	$this->set('title_for_layout','Login');
	
	//Set the supplemental info
	$this->set('supplementalInfo', $this->_getContentMsg('login_supplemental_info'));
	
	//Lets customize the login view a bit depending on app conditions.
	if (!$this->Group->field('active', array('Group.id' => 2)))
		$this->set('loginMsg', $this->_getContentMsg('no_login'));
	elseif (!$this->Acl->check('Applicants','Applications/edit'))
		$this->set('loginMsg', $this->_getContentMsg('login_no_edit'));
	else 
		$this->set('loginMsg', $this->_getContentMsg('login_welcome'));
		
	//In this case we want to bypass the auth autoredirect.
	$this->Auth->redirect(array('controller' => 'users', 'action' => 'logout'));
}

///////////////////////////////////////////////////////////////////////////////	

function logout() {
	$this->redirect($this->Auth->logout());
}

///////////////////////////////////////////////////////////////////////////////	

function index() {
	$this->User->recursive = 0;
	$this->paginate = array('limit' => 10);
	$this->set('users', $this->paginate('User'));
	
}

///////////////////////////////////////////////////////////////////////////////	

function add() {
	if (!empty($this->data)) {
	  if ($this->data['User']['password'] 
	  	  == $this->Auth->password($this->data['User']['password_confirm'])) 
	  {
		$this->User->create();
		if ($this->User->save($this->data)) {
			//If this is an applicant, create subbordinate records.
			if($this->data['User']['group_id'] == 2) {//an applicant
				$this->data['Application']['user_id'] = $this->User->id;
								
				if ($this->Application->save($this->data['Application'], false)) {
					$app_id = $this->Application->id;
					$usrR = & $this->User;
					$appR = & $this->Application;
					if(!($this->Acl->allow($usrR, $appR) &&
							 $this->Acl->allow($usrR, $usrR))) {
						$this->Session->setFlash(__('There was an error with permissions. Please, try again.', true),
																		'flash_failure');
					}
					
					//set up data for all of the related records then create them.
					$this->data['Score']['application_id'] =$app_id;
					$this->data['Studyinterest']['application_id'] = $app_id;
					$this->data['Courselist']['application_id'] = $app_id;
									
					if (!$this->Score->save($this->data['Score'], false)) {
						$this->Session->setFlash(__('There was an error saving Score. Please, try again.', true),
																		'flash_failure');
					}
									
					if (!$this->Studyinterest->save($this->data['Studyinterest'], false)) {
						$this->Session->setFlash(__('There was an error saving Study Interest. Please, try again.', true),
																		'flash_failure');
					}
									
					if (!$this->Courselist->save($this->data['Courselist'], false)) {
						$this->Session->setFlash(__('There was an error saving Courselist. Please, try again.', true),
																		'flash_failure');
					}
				} //end if application saved.
				
			} //end if applicant.
			else {
				$usrR = & $this->User;
				$this->Acl->allow($usrR, $usrR);
				debug("Hello");
			}
			$this->Session->setFlash(__('The user has been saved', true),'flash_success');
			$this->redirect(array('action' => 'index'));
		} else {
			$this->Session->setFlash(
				__('The user could not be saved. Please, try again.', true),
				'flash_failure');
		}
	  } else {
		$this->Session->setFlash(
			__('The users passwords did not match, the record was not saved.', true),
			'flash_failure');
	  }
	}
	$groups = $this->User->Group->find('list');
	$this->set(compact('groups'));
}

///////////////////////////////////////////////////////////////////////////////	

function edit($id = null) {

	if (!$id && empty($this->data)) {
		$this->Session->setFlash(__('Invalid user', true), 'flash_failure');
		$this->redirect($this->referer());
	}
	if (!empty($this->data)) {
		//Check to see if the password is changing.
		if (array_key_exists('passwd', $this->data['User'])) {
		 	if(!empty($this->data['User']['new_password']) 
		 		 && (strlen($this->data['User']['new_password']) > 6)
		 		 && $this->data['User']['new_password'] == $this->data['User']['confirm_password'])	 
	  	{
	  		$this->data['User']['password'] = $this->Auth->password($this->data['User']['new_password']);
	  	} else {
				$this->Session->setFlash(
						__('Passwords must match and be longer than 6 characters. Please, try again.', 
							 true), 'flash_failure');
				return;
			}
		} //if passwd
		if ($this->User->save($this->data)) {
			$this->Session->setFlash(__('The user has been saved', true), 'flash_success');
		} else {
			$this->Session->setFlash(
				__('The user could not be saved. Please, try again.', true), 'flash_failure');
		}	
	}
	
	if (empty($this->data)) {
		$this->data = $this->User->read(null, $id);
	}
	$this->set('app_id', $this->User->data['Application']['id']);
	$groups = $this->User->Group->find('list');
	$this->set(compact('groups'));
}

///////////////////////////////////////////////////////////////////////////////	

function delete($id = null) {
	if (!$id) {
		$this->Session->setFlash(__('Invalid id for user', true), 'flash_failure');
		$this->redirect($this->referer());
	}
	
	if ($this->User->delete($id)) {
		$this->Session->setFlash(__("User deleted", true), 'flash_success');
		$this->redirect(array('action'=>'index'));
	}
	$this->Session->setFlash(__('User was not deleted', true), 'flash_failure');
	$this->redirect(array('action' => 'index'));
}

/**
	* Upload users from a data file.
	*/
function upload() {
	if(!empty($this->data) && $this->User->isUploadedFile($this->data['User'])) {
		
		ini_set('auto_detect_line_endings', true); // work with Mac files too.
		$file = file($this->data['User']['file']['tmp_name']);
		$line_count= count($file);
		$rec_count = 0;
		$mal_rec_count = 0;
		$report_errors = array();
		$masters_errors= array();
		
		foreach ($file as $row) {
			$rec_count++;
			$bad_rec= false; //any error will set this true, so our sum is correct.
			
			$record = explode ("\t", $row);
			if (count($record) == 77) {
				$applicant = null;
				// if this is a masters app we don't want to add the record
				if (strcasecmp(trim($record[12]), 'master\'s degree') == 0) {
					$masters_errors[$rec_count] = 'The record '. $rec_count .' was a master\'s degree application.';
					continue;
				}
				//user data fields. User has one application
				$applicant['User']['username'] = trim($record[0]);
				if ($applicant['User']['username'] != trim($record[0])) {
					$report_errors[$rec_count] = 'Username has illegal characters on line' . $rec_count;
					$mal_rec_count++;
					continue;
				}
				
				$applicant['User']['password'] = $this->Auth->password(trim($record[1]));
				$applicant['User']['email'] = trim($record[2]);
				$applicant['User']['group_id'] = 2; //Applicant
				
				$usr= $this->User->findByUsername($applicant['User']['username'], array('id'));
				if (!empty($usr['User']['id'])) {
					$report_errors[$rec_count] = 'Duplicate username on line' . $rec_count;
					$mal_rec_count++;
					continue;		
				}
				
				//application data fields. Application has one Pif
				$applicant['Application']['edhistory_mod'] = $applicant['Application']['pif_mod'] = date('Y-m-d H:i:s');
				$applicant['Application']['edhistory_stat'] = $applicant['Application']['pif_stat'] = 'green';
				 
				$applicant['Application']['lastname'] = trim($record[3]);
				$applicant['Application']['firstname'] = trim($record[4]);
				$applicant['Application']['middlename'] = trim($record[5]);
				$applicant['Application']['uscitizen_stat'] = (strcasecmp(trim($record[10]), 'us citizen') == 0)? 1 : 0;
				$applicant['Application']['uscitizen_info'] = trim($record[7]);
				$address = trim($record[15]) . "\n";
				$address .= trim($record[16]) . "\n";
				$address .= trim($record[17]) . ', ';
				$address .= trim($record[18]) . ' ';
				$address .= trim($record[19]) . "\n";
				$address .= trim($record[20]);
				
				$applicant['Application']['address'] = $address;
				$applicant['Applicaiton']['phone_pri'] = trim($record[21]);
				
				$applicant['Application']['toefl_req'] = !$applicant['Application']['uscitizen_stat'];
				
				/**
				* There are up to 4 schools, if they have been filled out the 
				* file record will have the following numbers at the indexes.
				*/
				$max = 0;
				if ($record[39] == 1)
					++$max;
				if ($record[48] == 2)
					++$max;
				if ($record[57] == 3)
					++$max;
				if ($record[66] == 4)
					++$max;
				
				$bi = 40; //baseSchool index.
				$nf = 9; //Number of fields in school.
				// $nf*$i+$bi+n sets index offset for input array see gradweb admissionsDataKey.
				if ($max > 0) {
					for ($i=0; $i < $max; $i++) {
						$applicant['School'][$i]['schoolname'] = trim($record[($nf*$i+$bi)]);
						$applicant['School'][$i]['degrees'] = trim($record[($nf*$i+$bi+4)]);
						$st = explode('/', $record[($nf*$i+$bi+6)]);
						$applicant['School'][$i]['start_date'] = trim($st[1]). '-'. trim($st[0]). '-1';
						$st = explode('/', $record[($nf*$i+$bi+7)]);
						$applicant['School'][$i]['end_date'] = trim($st[1]). '-'. trim($st[0]). '-1';
					} //end for loop.
				} //end num schools > 0.
												
				/*
				* Now we save the record. We'll save the related records at the same time, 
				* relying on cake to transactionally insert the records.
				*/
				$this->User->create();
				$bSaved = false; 
				$bSubSaved = false;
				
				$bSaved = $this->Application->saveAll($applicant);
				
				if($bSaved) {
					
					$applicant['Courselist']['application_id'] = $this->Application->id;
					$applicant['Studyinterest']['application_id'] = $this->Application->id;
					$applicant['Score']['application_id'] = $this->Application->id;
					
					$bSubSaved = ($this->Courselist->save($applicant['Courselist'])
											&& $this->Studyinterest->save($applicant['Studyinterest'])
											&& $this->Score->save($applicant['Score'])); 
					
				}
				
				if($bSaved && $bSubSaved) {
					
					$usrR = & $this->User;
					$appR = & $this->Application;
					if(!($this->Acl->allow($usrR, $appR) &&
							 $this->Acl->allow($usrR, $usrR))) {
						$report_errors[$rec_count] = 'There was an error with permissions on record; ' . $rec_count;
						$bad_rec=true;
					}				
									
					//Grab the email content.
					$message =  $this->_getContentMsg($key = 'new_applicant_email');
					//Now email the student.
					if (!$this->_sendEmailMsg($this->User->field('email'), 
														 'UO Department of Psychology'
														 . ' Online Admissions Application'
														 .' Confirmation', $message, 
														 array( 'full_name' => 
																		$this->Application->field('firstname')
																		. ' ' 
																		. $this->Application->field('lastname')))) 
					{
						$report_errors[$rec_count] = 'There was an error emailing the applicant on line' . $rec_count;
						$bad_rec=true;
					}			
				} else { //problem saving.					
					$report_errors[$rec_count] = 'There was an error saving applicaiton on line; ' . $rec_count;
					$bad_rec=true;
				}
			} else {
				$report_errors[$rec_count] = 'Line number ' . $rec_count . ' is malformed.';
				$bad_rec=true;
			}
			
			if ($bad_rec) $mal_rec_count++;
			
		} //end foreach line in file.
					
		//set these for reporting results of the upload.
		$this->set('line_count', $line_count);
		$this->set('mal_rec_count', $mal_rec_count);
		$this->set('errors', $report_errors);
		$this->set('masters', $masters_errors);
		
	} else if(!empty($this->data)) { //end if file exists.
	  $this->Session->setFlash('Error uploading file', 'flash_failure');	
	}

	unset($this->data['Application']);
} //end function upload

/**
	* Default action control
	*/
	function activate() {
			
		if (empty($this->data)) {
			$this->data = array();
			$this->data['applicants-login'] = ($this->Group->field('active', array('Group.id' => 2)))? 'y':'n';
			$this->data['applicants-editing_priv'] = ($this->Acl->check('Applicants','Applications/edit'))? 'y':'n';
			$this->data['faculty-login'] = ($this->Group->field('active', array('Group.id' => 3)))? 'y':'n';
			$this->data['students-login'] = ($this->Group->field('active', array('Group.id' => 5)))? 'y':'n';
		} else {
		
			$this->Group->id = 2;
			$this->Group->set('active', ($this->data['applicants-login'] == 'y'));
			$this->Group->save();
			
			$this->Group->id = 3;
			$this->Group->set('active', ($this->data['faculty-login'] == 'y'));
			$this->Group->save();
		
			$this->Group->id = 5;
			$this->Group->set('active', ($this->data['students-login'] == 'y'));
			$this->Group->save();
			
			if($this->data['applicants-editing_priv'] == 'y') {
				$this->Acl->allow('Applicants','controllers/Applications');
				$this->Acl->allow('Applicants','controllers/Attachments');
				$this->Acl->allow('Applicants','controllers/Courselists');
				$this->Acl->allow('Applicants','controllers/References');
				$this->Acl->allow('Applicants','controllers/Schools');
				$this->Acl->allow('Applicants','controllers/Studyinterests');
				
			} else {
				$this->Acl->deny('Applicants','controllers/Applications');
				$this->Acl->deny('Applicants','controllers/Attachments');
				$this->Acl->deny('Applicants','controllers/Courselists');
				$this->Acl->deny('Applicants','controllers/References');
				$this->Acl->deny('Applicants','controllers/Schools');
				$this->Acl->deny('Applicants','controllers/Studyinterests');
			}	
		}// end else there has been a submission
	} // end index function.


} // end controller.
